/****************************************
 * Copyright (c) 2005-2008 by Cbean.net
 * All right reserved.
 * Create Date: 12:53:55
 * Create Author: Simon.Wu
 * Author E-Mail: mimousewu@gmail.com
 * File Name:  Dispatcher.java
 * Last Update Date:
 * Change Log:
 * ====================================================================
 * $RCSfile: Dispatcher.java,v $  $Revision: 1.0 $  $Date: 12:53:55 $
 * $Log: Dispatcher.java,v $
 * ====================================================================
 ****************************************/
package net.cbean.cmd;

import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import net.cbean.io.ClasspathUtil;

/**
 * @author Simon.Wu <br>
 * <a href="mailto:mimousewu@gmail.com">mimousewu@gmail.com</a><p>
 * 
 */
public class Dispatcher {
	
	public static final String INIT_CMD = "INIT_CMD";
	
	private Map<String,Command> commands = new HashMap<String,Command>();
	
	private String initCmd;
	
	public Dispatcher(){}
	
	public Dispatcher(String classpathConfig){
		int idx = classpathConfig.lastIndexOf('/');
		String pkg = "";
		if(idx >0){
			pkg = classpathConfig.substring(0,idx);
			classpathConfig  = classpathConfig.substring(idx+1);
		}
		try {
			for(InputStream in: ClasspathUtil.findPackageFiles(pkg, classpathConfig)){
				loadCommandConfig(in);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	public Command getCommand(String cmd) {
		return commands.get(cmd);
	}
	
	public void loadCommandConfig(String cmdConfFile){
		loadCommandConfig(getClass().getClassLoader().getResourceAsStream(cmdConfFile));
	}

	private void loadCommandConfig(InputStream in){
		Properties p = new Properties();
		try {
			p.load(in );
			
			for(Map.Entry<Object, Object> entry : p.entrySet()){
				String key = entry.getKey().toString();
				String value = entry.getValue().toString();
				if(commands.containsKey(key)){
					throw new IllegalArgumentException("Dumplicate configurations of command " + key);
				}
				if(INIT_CMD.equals(key)){
					initCmd = value;
				}else{
					commands.put(key, (Command)Class.forName(value).newInstance());
				}
			}
		} catch (Exception e) {
			throw new IllegalArgumentException("can't init command configurations.",e);
		}
	}

	public Map<String, Command> getCommands() {
		return commands;
	}

	public Command getInitCommand() {
		if(initCmd!=null){
			return getCommand(initCmd);
		}else{
			return null;
		}
	}
	
}
